package com.zz.framework.widget

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.animation.DecelerateInterpolator
import android.widget.OverScroller
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.max


/**
 * Copyright © 2025 zhun All rights reserved.
 * Created by ZhaoZhun on 2025/3/6 10:56.
 * @author: ZhaoZhun 1820022519@qq.com
 * @version: V1.0
 */
class ElasticOverScrollRecyclerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : RecyclerView(context, attrs, defStyleAttr) {
    private var maxOverScrollDistance = 200 // 允许的最大拉伸距离（像素）
    private val scroller = OverScroller(context, DecelerateInterpolator())
    private var lastY = 0f // 记录上一次触摸的 Y 坐标
    private var isOverScrolling = false // 是否处于超出滚动状态
    fun setMaxOverScrollDistance(distance: Int) {
        maxOverScrollDistance = distance
    }

    override fun onOverScrolled(scrollX: Int, scrollY: Int, clampedX: Boolean, clampedY: Boolean) {
        val maxScrollY = computeVerticalScrollRange() - height

        when {
            scrollY < 0 -> { // 处理下拉超出边界
                val newScrollY = scrollY.coerceAtLeast(-maxOverScrollDistance)
                super.onOverScrolled(scrollX, newScrollY, clampedX, clampedY)
                isOverScrolling = true
            }
            scrollY > maxScrollY -> { // 处理上拉超出边界
                val newScrollY = scrollY.coerceAtMost(maxScrollY + maxOverScrollDistance)
                super.onOverScrolled(scrollX, newScrollY, clampedX, clampedY)
                isOverScrolling = true
            }
            else -> {
                super.onOverScrolled(scrollX, scrollY, clampedX, clampedY)
                isOverScrolling = false
            }
        }
    }

    override fun onTouchEvent(e: MotionEvent): Boolean {
        when (e.action) {
            MotionEvent.ACTION_DOWN -> {
                lastY = e.y
                isOverScrolling = false
            }

            MotionEvent.ACTION_MOVE -> {
                val deltaY = e.y - lastY
                lastY = e.y

                if (!canScrollVertically(-1) && deltaY > 0) { // 顶部下拉
                    scrollBy(0, (-deltaY / 2).toInt()) // 让下拉更柔和
                    return true
                } else if (!canScrollVertically(1) && deltaY < 0) { // 底部上拉
                    scrollBy(0, (-deltaY / 2).toInt())
                    return true
                }
            }

            MotionEvent.ACTION_UP -> {
                if (isOverScrolling) resetScroll() // 松手后回弹
            }
        }
        return super.onTouchEvent(e)
    }

    private fun resetScroll() {
        if (scrollY != 0) {
            scroller.startScroll(0, scrollY, 0, -scrollY, 500)
            invalidate()
        }
    }

    override fun computeScroll() {
        if (scroller.computeScrollOffset()) {
            scrollTo(0, scroller.currY)
            postInvalidate()
        }
    }
}